home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************/
- /* scull.c */
- /* */
- /* Shaft culling using [Haines and Wallace91] algorithm */
- /* */
- /* Copyright (C) 1992, Bernard Kwok */
- /* All rights reserved. */
- /* Revision 1.0 */
- /* May, 1992 */
- /**********************************************************************/
- #include <stdio.h>
- #include <math.h>
- #include "geo.h"
- #include "struct.h"
- #include "misc.h"
- #include "io.h"
- #include "bvol.h"
- #include "scull.h"
-
- extern double Poly_PlaneD();
- extern OptionType Option;
- extern BoundingBoxType BoxPoly();
- extern int Bounds_Compare();
- extern int objlist_size;
- extern void BoxInit();
- extern Vector Nearest_Point(), Farthest_Point();
- extern FILE *rlogfile;
-
- /**********************************************************************/
- BoundingBoxType extentbox; /* Minimum extent box around bounding boxes */
- RefListtype scull, rcull; /* Edges of culling shaft */
- PlaneSettype planeset; /* Planes in culling shaft */
- ShaftStatstype ShaftStats; /* Shaft statistics */
-
- /**********************************************************************/
- /* Initialize shaft stats for current shaft */
- /**********************************************************************/
- void StartShaft()
- {
- ShaftStats.BoxIn = ShaftStats.BoxOut = ShaftStats.BoxOverlap =
- ShaftStats.BoxContains = ShaftStats.BoxTests = 0;
- ShaftStats.candCube = ShaftStats.candSphere = ShaftStats.candCone =
- ShaftStats.candMesh = ShaftStats.candCyl = ShaftStats.candHbox = 0;
- ShaftStats.candidates = 0;
- }
-
- /**********************************************************************/
- /* Initialize stats for all shafts */
- /**********************************************************************/
- void Init_ShaftStats()
- {
- ShaftStats.total_BoxIn = ShaftStats.total_BoxOut =
- ShaftStats.total_BoxOverlap =
- ShaftStats.BoxContains = ShaftStats.BoxTests = 0;
- ShaftStats.total_shafts = 0;
- ShaftStats.total_candidates = 0;
- }
-
- /**********************************************************************/
- /* Update stats for shaft(s) */
- /**********************************************************************/
- void Update_ShaftStats(candidate, primid)
- int candidate;
- int primid;
- {
- switch (candidate) {
- case INSIDE: ShaftStats.BoxIn++; break;
- case OVERLAP: ShaftStats.BoxOverlap++; break;
- case CONTAINS: ShaftStats.BoxContains++; break;
- case OUTSIDE: ShaftStats.BoxOut++; break;
- default: break;
- }
-
- if (candidate != OUTSIDE) {
- switch (primid) {
- case CONE: ShaftStats.candCone++; break;
- case CUBE: ShaftStats.candCube++; break;
- case SPHERE: ShaftStats.candSphere++; break;
- case CYLINDER: ShaftStats.candCyl++; break;
- case MESH: ShaftStats.candMesh++; break;
- case HBOX: ShaftStats.candHbox++; break;
- default:
- fprintf(stderr, "Invalid candidate list primitive.\n");
- exit(1);
- }
- ShaftStats.candidates++;
- }
- }
-
- /**********************************************************************/
- /* Print plane info */
- /**********************************************************************/
- void Print_Plane(pl)
- Plane pl;
- {
- printf("N=%g,%g,%g d=%g, pt=%g,%g,%g\n",
- pl.n.x, pl.n.y, pl.n.z, pl.d, pl.p.x, pl.p.y, pl.p.z);
- }
-
- /**********************************************************************/
- /* Print shaft information */
- /**********************************************************************/
- void Print_Shaft(src,rec, fptr)
- Polygon *src, *rec;
- FILE *fptr;
- {
- int i;
-
- fprintf(fptr,"\n\t** Shaft Information **\n");
- fprintf(fptr,"\t|Candidate|= %d for patch%d and patch%d built\n",
- objlist_size, src->id, rec->id);
-
- fprintf(fptr,"\tSource reference list ( ");
- for(i=0;i<6;i++) fprintf(fptr,"%d ", scull.dir[i]);
- fprintf(fptr,")\n");
-
- fprintf(fptr,"\tReceiver reference list ( ");
- for(i=0;i<6;i++) fprintf(fptr,"%d ", rcull.dir[i]);
- fprintf(fptr,")\n");
-
- fprintf(fptr,"\t|Plane Set|=%d {\n", planeset.num_planes);
- for (i=0;i<planeset.num_planes;i++) {
- fprintf(fptr,"\tPlane[%d]: ",i);
- Print_Plane(planeset.planes[i]);
- }
- fprintf(fptr,"\t}\n");
-
- BoundsPrint(extentbox, stdout, "Extent Box");
- }
-
- /**********************************************************************/
- /* Print stats for current iteration or final stats */
- /**********************************************************************/
- void EndShaft(final_stats, fptr)
- int final_stats;
- FILE *fptr;
- {
- FILE *fp;
-
- if (Option.device == PRINT)
- fp = stdout;
- else fp = fptr;
-
- if (!final_stats) {
- ShaftStats.total_shafts++;
- ShaftStats.total_candidates += ShaftStats.candidates;
- ShaftStats.total_BoxTests += ShaftStats.BoxTests;
- ShaftStats.total_BoxOverlap += ShaftStats.BoxOverlap;
- ShaftStats.total_BoxContains += ShaftStats.BoxContains;
- ShaftStats.total_BoxOut += ShaftStats.BoxOut;
- ShaftStats.total_BoxIn += ShaftStats.BoxIn;
- }
-
- if (Option.statistics) {
- if (final_stats || Option.device == PRINT) {
- fprintf(fp,"\n\tShaft Culling Statistics\n");
- fprintf(fp,"\t--------------------------\n");
- fprintf(fp,"\tStrategy used: ");
- switch (ShaftStats.strategy) {
- case RATIO_OPEN:
- fprintf(fp,"\tRatio open = %g\n", ShaftStats.ratio_open); break;
- case KEEP_CLOSED: fprintf(fp,"Keep closed\n"); break;
- case ALWAYS_OPEN: fprintf(fp,"Always open\n"); break;
- case OVERLAP_OPEN: fprintf(fp,"Overlap open\n"); break;
- default: fprintf(fp,"Unknown ???\n");
- }
-
- if (Option.tablelog) {
- switch (ShaftStats.strategy) {
- case RATIO_OPEN:
- fprintf(rlogfile,"RO %g \\\\\n", ShaftStats.ratio_open); break;
- case KEEP_CLOSED: fprintf(rlogfile,"KC \\\\\n"); break;
- case ALWAYS_OPEN: fprintf(rlogfile,"AO \\\\\n"); break;
- case OVERLAP_OPEN: fprintf(rlogfile,"OO \\\\\n"); break;
- default: fprintf(rlogfile,"Unknown ??? \\\\\n");
- }
- }
- }
- if (!final_stats) {
- if (Option.device == PRINT) {
- fprintf(fp,"\tNumber volumes tested: %d\n", ShaftStats.BoxTests);
- fprintf(fp,"\t%In=%d; Out=%d; Overlap=%d; Contains=%d\n",
- ShaftStats.BoxIn,
- ShaftStats.BoxOut,
- ShaftStats.BoxOverlap,
- ShaftStats.BoxContains);
-
- fprintf(fp,"\tNumber of candidates %d\n", ShaftStats.candidates);
- fprintf(fp,"\tCube=%d; Cone=%d; Cyl=%d; Sph=%d; Mesh=%d; HBV=%d\n",
- ShaftStats.candCube,
- ShaftStats.candCone,
- ShaftStats.candCyl,
- ShaftStats.candSphere,
- ShaftStats.candMesh,
- ShaftStats.candHbox);
- }
- } else {
- fprintf(fp,"\tTotal boxes tested: %d\n", ShaftStats.total_BoxTests);
- fprintf(fp,"\t%In=%d; Out=%d; Overlap=%d; Contains=%d\n",
- ShaftStats.total_BoxIn,
- ShaftStats.total_BoxOut,
- ShaftStats.total_BoxOverlap,
- ShaftStats.total_BoxContains);
- fprintf(fp,"\tTotal number of candidates: %d\n",
- ShaftStats.total_candidates);
- fprintf(fp,"\tAverage candidates per shaft: %2.2f\n",
- (float) ShaftStats.total_candidates /
- (float) ShaftStats.total_shafts);
-
- if (Option.tablelog) {
- fp = rlogfile;
- fprintf(fp,"%d \\\\\n", ShaftStats.total_BoxTests);
- fprintf(fp,"%d \\\\\n%d \\\\\n%d \\\\\n%d \\\\\n",
- ShaftStats.total_BoxIn,
- ShaftStats.total_BoxOut,
- ShaftStats.total_BoxOverlap,
- ShaftStats.total_BoxContains);
- fprintf(fp,"%d \\\\\n",
- ShaftStats.total_candidates);
- fprintf(fp,"%g \\\\\n",
- (float) ShaftStats.total_candidates /
- (float) ShaftStats.total_shafts);
- }
- }
- printf ("\n");
- }
- }
-
- /**********************************************************************/
- /* Form EXTENT BOX containing reference items, and find culling edges */
- /**********************************************************************/
- void Form_Extent_Culledges(extentbox, scull, rcull, sbox, rbox)
- BoundingBoxType *extentbox, sbox, rbox;
- RefListtype *scull, *rcull;
- {
- int i;
-
- /* Initialize reference item lists, and extent box */
- for (i=0;i<6;i++)
- scull->dir[i] = rcull->dir[i] = FALSE;
- BoxInit(extentbox);
-
- /* Check min x coordinates */
- if (sbox.min.x < rbox.min.x) {
- scull->pt[MINX] = extentbox->min.x = sbox.min.x;
- scull->dir[MINX] = TRUE;
- } else {
- rcull->pt[MINX] = extentbox->min.x = rbox.min.x;
- if (sbox.min.x != rbox.min.x)
- rcull->dir[MINX] = TRUE;
- }
-
- /* Check min y coordinates */
- if (sbox.min.y < rbox.min.y) {
- scull->pt[MINY] = extentbox->min.y = sbox.min.y;
- scull->dir[MINY] = TRUE;
- } else {
- rcull->pt[MINY] = extentbox->min.y = rbox.min.y;
- if (sbox.min.y != rbox.min.y)
- rcull->dir[MINY] = TRUE;
- }
-
- /* Check min z coordinates */
- if (sbox.min.z < rbox.min.z) {
- scull->pt[MINZ] = extentbox->min.z = sbox.min.z;
- scull->dir[MINZ] = TRUE;
- } else {
- rcull->pt[MINZ] = extentbox->min.z = rbox.min.z;
- if (sbox.min.z != rbox.min.z)
- rcull->dir[MINZ] = TRUE;
- }
-
- /* Check max x coordinates */
- if (sbox.max.x > rbox.max.x) {
- scull->pt[MAXX] = extentbox->max.x = sbox.max.x;
- scull->dir[MAXX] = TRUE;
- } else {
- rcull->pt[MAXX] = extentbox->max.x = rbox.max.x;
- if (sbox.max.x != rbox.max.x)
- rcull->dir[MAXX] = TRUE;
- }
-
- /* Check max y coordinates */
- if (sbox.max.y > rbox.max.y) {
- scull->pt[MAXY] = extentbox->max.y = sbox.max.y;
- scull->dir[MAXY] = TRUE;
- } else {
- rcull->pt[MAXY] = extentbox->max.y = rbox.max.y;
- if (sbox.max.y != rbox.max.y)
- rcull->dir[MAXY] = TRUE;
- }
-
- /* Check max z coordinates */
- if (sbox.max.z > rbox.max.z) {
- scull->pt[MAXZ] = extentbox->max.z = sbox.max.z;
- scull->dir[MAXZ] = TRUE;
- } else {
- rcull->pt[MAXZ] = extentbox->max.z = rbox.max.z;
- if (sbox.max.z != rbox.max.z)
- rcull->dir[MAXZ] = TRUE;
- }
- }
-
- /**********************************************************************/
- /* Form plane set from reference lists: */
- /* Form all combinations of elements on one reference list with those */
- /* on the other, ignoring combinations with matching directions */
- /* (X, Y or Z) */
- /**********************************************************************/
- void Form_Plane_Set(planeset, scull, rcull, sbox, rbox)
- PlaneSettype *planeset;
- RefListtype scull, rcull;
- BoundingBoxType sbox, rbox;
- {
- int i,j;
- Vector plane_pt; /* Vector used to compute plane distance */
- Vector N;
- double d, tmp;
-
- planeset->num_planes = 0;
- for (i=0;i<6;i++) /* Check all/any source cull edges */
- for(j=0;j<6;j++) /* Check all/any receiver cull edges */
- if ((i != j) && scull.dir[i] && rcull.dir[j]) {
- if ( ((i < j) && ((i+3) != j)) || ((i > j) && ((j+3) != i)) ) {
-
- /* Form a new plane for plane set of culling shaft.
- Note: sample point on plane taken from source box,
- could just as well be taken from the receiver box */
- planeset->planes[planeset->num_planes].n.x = 0.0;
- planeset->planes[planeset->num_planes].n.y = 0.0;
- planeset->planes[planeset->num_planes].n.z = 0.0;
- plane_pt.x = plane_pt.y = plane_pt.z = 0.0;
-
- /* Check source edge list */
- switch (i) {
- case MINX:
- plane_pt.x = sbox.min.x; tmp = rbox.min.x - sbox.min.x;
- break;
- case MAXX:
- plane_pt.x = sbox.max.x; tmp = rbox.max.x - sbox.max.x;
- break;
- case MINY:
- plane_pt.y = sbox.min.y; tmp = rbox.min.y - sbox.min.y;
- break;
- case MAXY:
- plane_pt.y = sbox.max.y; tmp = rbox.max.y - sbox.max.y;
- break;
- case MINZ:
- plane_pt.z = sbox.min.z; tmp = rbox.min.z - sbox.min.z;
- break;
- case MAXZ:
- plane_pt.z = sbox.max.z; tmp = rbox.max.z - sbox.max.z;
- break;
- default:
- fprintf(stderr,"Invalid axial direction of source edge\n");
- exit(1);
- }
- if (j == MINX || j == MAXX)
- planeset->planes[planeset->num_planes].n.x = tmp;
- else if (j == MINY || j == MAXY)
- planeset->planes[planeset->num_planes].n.y = tmp;
- else if (j == MINZ || j == MAXZ)
- planeset->planes[planeset->num_planes].n.z = tmp;
-
- /* Check receiver edge list */
- switch (j) {
- case MINX:
- plane_pt.x = sbox.min.x; tmp = sbox.min.x - rbox.min.x;
- break;
- case MAXX:
- plane_pt.x = sbox.max.x; tmp = sbox.max.x - rbox.max.x;
- break;
- case MINY:
- plane_pt.y = sbox.min.y; tmp = sbox.min.y - rbox.min.y;
- break;
- case MAXY:
- plane_pt.y = sbox.max.y; tmp = sbox.max.y - rbox.max.y;
- break;
- case MINZ:
- plane_pt.z = sbox.min.z; tmp = sbox.min.z - rbox.min.z;
- break;
- case MAXZ:
- plane_pt.z = sbox.max.z; tmp = sbox.max.z - rbox.max.z;
- break;
- default:
- fprintf(stderr,"Invalid axial direction of receiver edge\n");
- exit(1);
- }
- if (i == MINX || i== MAXX)
- planeset->planes[planeset->num_planes].n.x = tmp;
- else if (i == MINY || i== MAXY)
- planeset->planes[planeset->num_planes].n.y = tmp;
- else if (i == MINZ || i== MAXZ)
- planeset->planes[planeset->num_planes].n.z = tmp;
-
- /* Find normal vector and d */
- N = planeset->planes[planeset->num_planes].n;
- norm(&N);
- d = Poly_PlaneD(N, plane_pt);
-
- /* Check direction of normal */
- if (!Bounds_Behind_Plane(&sbox, N, d) ||
- !Bounds_Behind_Plane(&rbox, N, d)) {
- N = *vnegate(&N);
- d = -d;
- }
- /* Store N, d and pt on plane */
- planeset->planes[planeset->num_planes].n = N;
- planeset->planes[planeset->num_planes].d = d;
- planeset->planes[planeset->num_planes].p = plane_pt;
-
- planeset->num_planes++;
- }
- }
- }
-
- /**********************************************************************/
- /* Find culling shaft between bounding boxes of source and receiver */
- /**********************************************************************/
- void Form_Culling_Shaft(sbox, rbox)
- BoundingBoxType sbox, rbox;
- {
- /* Form extent box and culling edges */
- Form_Extent_Culledges(&extentbox, &scull, &rcull, sbox, rbox);
-
- /* Generate all planes which connect the edges of the 2
- reference boxes. */
- Form_Plane_Set(&planeset, scull, rcull, sbox, rbox);
- }
-
- /**********************************************************************/
- /* Find out if test box is a candidate */
- /**********************************************************************/
- int isCandidate(box, extbox, sbox, rbox, planeset)
- BoundingBoxType *box, *extbox, *sbox, *rbox;
- PlaneSettype planeset;
- {
- int i;
- int candidate = OUTSIDE; /* Assume box is outside */
- Vector near_corner, far_corner; /* Near and far corners of box */
- Vector N;
- double d;
- char *tmp = " ";
-
- /* Test if test volume is inside, outside or overlapping extent box */
- candidate = Bounds_Compare(box,extbox);
- if ((candidate == CONTAINS) || (candidate == OUTSIDE))
- return candidate;
-
- /* Test if test volume overlaps either reference item's bounding box */
- candidate = Bounds_Compare(box,sbox);
- if (candidate == OVERLAP || candidate == CONTAINS) return OVERLAP;
- candidate = Bounds_Compare(box,rbox);
- if (candidate == OVERLAP || candidate == CONTAINS) return OVERLAP;
-
- /* Test test volume against each plane of plane set */
- i = 0;
- candidate = INSIDE;
- while ((candidate != OUTSIDE || candidate != OVERLAP)
- && i < planeset.num_planes)
- {
- N = planeset.planes[i].n;
- d = planeset.planes[i].d;
- near_corner = Nearest_Point(box, N, d);
- far_corner = Farthest_Point(box, N, d);
- if (dot(&N, &near_corner) + d >= 0.0) { /* Outside shaft */
- candidate = OUTSIDE;
- } else if (dot(&N, &far_corner) + d > 0.0) { /* Overlaps shaft */
- candidate = OVERLAP;
- }
- i++;
- }
- return candidate;
- }
-
- int fdbg = 0;
- /**********************************************************************/
- /* Form candidate list for current shaft. Traverse BV tree recursively*/
- /* If not testing children of BV at current level, if none of it's */
- /* children is added then add the BV. Return number of BV's added at */
- /* current level to check. */
- /**********************************************************************/
- int Form_Candidate_List(shootPatch, recPatch, sbox, rbox, hbox)
- Polygon *shootPatch, *recPatch;
- BoundingBoxType *sbox, *rbox;
- HBBox *hbox;
- {
- int i;
- int candidate;
- float percent_overlap;
- int overlap_id;
- BoundingBoxType *test_box;
- int atlevel_added;
- int children_added;
- int same_father;
-
- atlevel_added = 0;
- if (hbox == NULL) return 0;
- test_box = hbox->box;
-
- /* Test if test box is in front of source and receiver first */
- candidate = ((1 - Bounds_Behind_Plane(test_box, shootPatch->normal[0],
- shootPatch->d)) &&
- (1 - Bounds_Behind_Plane(test_box, recPatch->normal[0],
- recPatch->d)) );
- if (!candidate) return 0;
-
- /* Test if box is inside the extent box, source or receiver box,
- and finally the shaft */
- candidate = isCandidate(test_box, &extentbox, sbox, rbox, planeset);
- ShaftStats.BoxTests++;
-
- /* "Discard" boxes outside the shaft */
- if (candidate == OUTSIDE) {
- Update_ShaftStats(candidate, Candidate_type(hbox));
- return 0;
- }
- /* else if at leaf level add to list */
- else if (IsLeafBox(hbox)) {
- Update_ShaftStats(candidate, Candidate_type(hbox));
- AddTo_ObjectList(hbox,candidate);
- return 1;
- }
-
- /* Test if is a primitive of type cone, box, sphere etc. If so, then
- if its inside or overlapping, just add to list.
- If contains only boxes can be discarded. */
- if (hbox->object != 0) {
- if (Candidate_type(hbox) != MESH) { /* Is not a mesh */
- if ((candidate == INSIDE) || (candidate == OVERLAP)) {
- Update_ShaftStats(candidate, Candidate_type(hbox));
- AddTo_ObjectList(hbox,candidate);
- atlevel_added++;
- }
-
- /* If "contains" and is a box, nothing inside can intersect with
- shaft, else add to list (assume non-mesh ray-intersect test
- less than ray-polygon intersect test */
- else if (candidate == CONTAINS) {
- if (Candidate_type(hbox) != CUBE) {
- Update_ShaftStats(candidate, Candidate_type(hbox));
- AddTo_ObjectList(hbox,candidate);
- atlevel_added++;
- }
- }
- return atlevel_added;
- } /* not mesh */
- }
-
- /* If test box contains the extent box test descendents */
- if (candidate == CONTAINS) {
- children_added = 0;
- same_father = FALSE;
- for(i=0; i<hbox->num_children; i++) {
- if (same_father == FALSE)
- same_father = Bounds_Same(hbox->box, hbox->child[i]->box);
- children_added +=
- Form_Candidate_List(shootPatch, recPatch, sbox, rbox, hbox->child[i]);
- }
-
- /* Add containing box only if no descendents added, and box not same
- as any children, if any */
- /* if (hbox->father != NULL) */
- if ((children_added == 0) && (!same_father)) {
- if (fdbg) printf("Add contains\n");
- Update_ShaftStats(candidate, Candidate_type(hbox));
- AddTo_ObjectList(hbox,candidate);
- atlevel_added++;
- }
- return children_added+atlevel_added;
- }
-
- /* Test which strategy to use for list addition, if candidate
- overlaps or is inside the shaft */
- switch (ShaftStats.strategy) {
- case KEEP_CLOSED: /* Never check children, even if overlaps */
- if (fdbg) printf("Add keep closed\n");
- Update_ShaftStats(candidate, Candidate_type(hbox));
- AddTo_ObjectList(hbox,candidate);
- atlevel_added++;
- break;
-
- case ALWAYS_OPEN: /* Check all children bounding volumes */
- children_added = 0;
- for(i=0; i<hbox->num_children; i++)
- children_added +=
- Form_Candidate_List(shootPatch, recPatch, sbox, rbox, hbox->child[i]);
-
- /* if (children_added == 0) {
- if (fdbg) printf("Add always open\n");
- Update_ShaftStats(candidate, Candidate_type(hbox));
- AddTo_ObjectList(hbox,candidate);
- atlevel_added++;
- } else */
- atlevel_added += children_added;
- break;
-
- case OVERLAP_OPEN: /* Check children bounding volumes only if overlaps */
- if (candidate == OVERLAP || candidate == CONTAINS) {
- children_added = 0;
- for(i=0; i<hbox->num_children; i++)
- children_added += Form_Candidate_List(shootPatch, recPatch,
- sbox, rbox, hbox->child[i]);
- if (children_added == 0) {
- if (fdbg) printf("Add overlap open\n");
- Update_ShaftStats(candidate, Candidate_type(hbox));
- AddTo_ObjectList(hbox,candidate);
- atlevel_added++;
- } else
- atlevel_added += children_added;
- } else if (candidate == INSIDE) {
- if (fdbg) printf("Add overlap open\n");
- Update_ShaftStats(candidate, Candidate_type(hbox));
- AddTo_ObjectList(hbox,candidate);
- atlevel_added++;
- }
- break;
-
- case RATIO_OPEN: /* Check children bounding volumes only if overlaps,
- by given ratio */
- if (candidate == OVERLAP || candidate == CONTAINS) {
- percent_overlap = 0.0;
- if (hbox->num_children != 0) {
-
- /* Find number of children that are inside or overlap the shaft */
- for(i=0; i<hbox->num_children; i++) {
- test_box = hbox->child[i]->box;
- if (Bounds_Same(test_box, hbox->box)) {
- overlap_id = i;
- percent_overlap++;
- } else if (isCandidate(test_box, &extentbox, sbox, rbox, planeset)
- != OUTSIDE) {
- overlap_id = i;
- percent_overlap++;
- }
- }
-
- /* If only 1 child overlaps, just add it to candidate list */
- /* Otherwise find percentage of children that overlap */
- if (percent_overlap == 1) {
- if (fdbg) printf("Add ratio open\n");
- Update_ShaftStats(candidate, Candidate_type(hbox));
- AddTo_ObjectList(hbox->child[overlap_id],candidate);
- atlevel_added++;
- return atlevel_added;
- } else
- percent_overlap /= (float) hbox->num_children;
- }
-
- /* Check if ratio of overlap > user defined tolerance */
- if (percent_overlap > ShaftStats.ratio_open) {
- if (fdbg) printf("Add ratio open. Percent = %g\n", percent_overlap);
- Update_ShaftStats(candidate, Candidate_type(hbox));
- AddTo_ObjectList(hbox,candidate);
- atlevel_added++;
- } else { /* Open box */
- children_added = 0;
- for(i=0; i<hbox->num_children; i++)
- children_added +=
- Form_Candidate_List(shootPatch, recPatch, sbox, rbox,
- hbox->child[i]);
- if (children_added == 0) {
- if (fdbg) printf("Add ratio open\n");
- Update_ShaftStats(candidate, Candidate_type(hbox));
- AddTo_ObjectList(hbox,candidate);
- atlevel_added++;
- } else
- atlevel_added += children_added;
- }
-
- } else if (candidate == INSIDE) {
- if (fdbg) printf("Add ratio open\n");
- Update_ShaftStats(candidate, Candidate_type(hbox));
- AddTo_ObjectList(hbox,candidate);
- atlevel_added++;
- }
- break;
-
- default:
- fprintf(stderr,"Invalid cull strategy creating Clist\n");
- exit(1);
- }
-
- return atlevel_added;
- }
-
- /**********************************************************************/
- /* Perform shaft culling between two patches */
- /**********************************************************************/
- void ShaftCull(src,rec, sbox, rbox, hbox)
- Polygon *src, *rec;
- BoundingBoxType sbox, rbox;
- HBBox *hbox;
- {
- Form_Culling_Shaft(sbox, rbox);
- (void) Form_Candidate_List(src, rec, &sbox, &rbox, hbox);
- }
-